#ifndef SUDOKUDATA_H_
#define SUDOKUDATA_H_

#include <QList>
#include <QObject>
#include "SudokuCell.h"


/**
  * Class that contains all sudoku diagram cells
  * @author Łukasz Szybka
  */
class SudokuData : public QObject
{
    Q_OBJECT
public:

    SudokuData();
    SudokuData(int _sizeBox);
    SudokuData(QString sudokuNumbers);
    SudokuData(QString filePath, QString fileName);
    SudokuData(const SudokuData& other);//TODO!!! qobject doesn't have copy constructor!

    ~SudokuData();
    void construct(QString sudokuNumbers);

    //SudokuData& operator=(const SudokuData& other);//TODO!!! qobject doesn't have operator=!

    void excludeAllPossibl();
    void excludePossibl(int row, int col, int val);

    int findNakedSingles();

    int findHiddenSinglesInVect(QHash<int, SudokuCell*> map, int insertType = HiddenSingles);
    int findHiddenSingles();

    int findLockedCandidates1AndExclude();
    int findLockedCandidates2AndExclude();

    int findGroupsAndExclude();
    int findGroupsInVectorAndExclude(QList<SudokuCell*> cellVector);

    int xWing();

    void sortByCluesAmount(QList<SudokuCell*> wektor);

    bool isBadNumber(int wier, int kol, int wartosc, bool sure = false);
    bool isSolvable();

    bool isFilled();
    bool isSolved();
    bool isValid();

    bool checkVector(QList<SudokuCell*> cellVector);//TODO const
    bool checkDiagram();//TODO const

    int getSize();
    int getSizeBox();
    int getCellCount();
    int getCellCount(int cellType);

    int getLockedCandidates1Count();
    int getLockedCandidates2Count();
    int getGroupsCount();
    int getXwingCount();

    void clear();

    const SudokuCell& cellAt(int row, int col) const;
    const SudokuCell& cellAt(int index) const;

    SudokuCell&	operator[](int index);

    double countPossibleSolutions();

    int countIndividuals();

    bool saveToFile(QString filePath, QString fileName);
    QByteArray readFromFile(QString filePath, QString fileName);

    friend QDebug operator<<(QDebug dbg, const SudokuData& sud);

signals:
    void valueFound(SudokuData data);
    void valueFound();
    void valueFound(int row, int col, int value, int method);
    void possiblExcluded(int index);
public slots:
    void solve(int solveMask = 0xffffff);

protected:
    void onFoundValue(int row, int col, int value, int method);
    void onFoundValue(int index, int value, int method);
    void onExcludePossibl(int index, int number, int method);


    //TODO check working and use
    QList<SudokuCell*> getBox(int index);


    QList<SudokuCell> cells;
    /**
      * Size of square box
      */
    int sizeBox;
    /**
      * Size of grid
      */
    int size;

    int lockedCandidates1Count;
    int lockedCandidates2Count;
    int groupsCount;
    int xWingCount;


private:
};

#endif /*SUDOKUDATA_H_*/
